HOWTO: HTML5 Video that works (almost) everywhere
So I got this video from a friend, and I wanted to post it on my site, but I wanted to do it without using any Flash, or any plugins, and I wanted it to work on the iPhone, and Chrome, and Firefox, and IE…
Step 1: Convert the file.
First I took the file and used Miro Video Converter to make two versions of the file. The first version I made was using the “Theora” format. This is an Ogg format, and you basically only need to make it for the video to show up in Firefox. Future versions of Firefox will support the WebM format instead (Chrome supports it now), so when Firefox 4 comes out, use that format.
Next, use Miro again and this time make a version using the iPhone preset. This basically creates an MP4 version of the file, but at the right resolution to have it show up on the iPhone. Annoyingly, the original file was from an iPhone, so it should have played, but it wouldn’t on mine. I suspect that the resolution difference between the iPhone 4 (used to make the video) and the iPhone 3GS (which I have) is the problem. Regardless, I just used the preset to downscale the video resolution.
Step 2: Adjust WordPress’ settings
WordPress didn’t like me uploading these files. Turned out that it was because I’m on multisite. In the Network Admin screen, find the Network Settings menu option, go to the bottom of the page, and add the mp4 and ogv extensions to the list of allowed files. Also add webm while you’re there, for the future.
Note: If you’re not on multisite but still have problems uploading the files, then add this line of code to your wp-config.php file, to turn on the unfiltered_upload capabilities for administrators:
define('ALLOW_UNFILTERED_UPLOADS',true);
Step 3: Check .htaccess settings
One of the things WordPress relies on to know if it’s a video or not is the MIME Type. Some servers have these properly configured, some don’t. Doesn’t hurt to help the process along by explicitly defining some of them in the .htaccess file. For good measure, I added a bunch of common ones, just to be sure:
AddType text/xml .xml AddType video/mp4 .mp4 .m4v AddType video/mpeg .mpeg .mpg AddType video/quicktime .mov AddType video/ogg .ogv AddType video/webm .webm AddType audio/mp4 .m4a .m4b .m4r AddType audio/mpeg .mp3 AddType audio/playlist .m3u AddType audio/x-scpls .pls AddType audio/ogg .ogg AddType audio/wav .wav
Step 4: Upload the videos
Easy one. Go into the Media->Library and upload your two videos. After doing that, get the URLs of both of them.
Step 5: Make the post
Make a new post and type in everything you want to type in. Then make sure you’re in the HTML editing mode, and add this code to the post:
<video width="640" height="360" controls> <source src="http://example.com/wp-content/uploads/video.mp4" type='video/mp4'></source> <source src="http://example.com/wp-content/uploads/video.ogv" type='video/ogg'></source> </video>
There’s a few things there you’ll need to manually edit.
Obviously the URLs need to point to your files. Also, it’s important that the MP4 one is first, some older iPad software doesn’t like it otherwise.
The second one is the width and height. Now, like with posting images, these don’t have to exactly match the actual width and height of the video. The browser will use these sizes and scale the video accordingly. However, you’ll want to get the aspect ratio correct, so you don’t stretch or squish the video into the wrong sized box. And you can leave the height and width out entirely to not scale it, if you got your sizes correct in the video itself. But it’s a good idea to have them there regardless, to clue the browser into the size beforehand and speed up page rendering. Also note that the iPhone doesn’t care about those width and height tags, since it will just show the video full screen when you tap on it.
Sidenote: Do NOT switch into Visual mode. TinyMCE will muck up this code, badly, and try to add a SWF player to it and Flash and a bunch of other stuff. This is probably by design, but I wanted to do this without Flash at all and see how that worked. Turns out to work fine in the browsers I tested.
Finally, preview and publish as normal.
Wantlist
One thing I haven’t figured out is how to target the iPhone specifically with a separate file. With this setup, Chrome and IE are now showing the iPhone file, which is lower resolution than the OGV file (which is at original resolution). In this specific case, the video was poor and so it doesn’t make much difference, but I’d prefer to have a separate file specified that only iPhones used without having to resort to user agent targeting.
EDIT: Turns out you can do this with a media query on the source that targets the iPhone. So here’s my new code:
<video width="640" height="360" controls> <source src="http://example.com/wp-content/uploads/video.iphone.mp4" type='video/mp4' media='only screen and (max-device-width: 480px)'></source> <source src="http://example.com/wp-content/uploads/video.mp4" type='video/mp4'></source> <source src="http://example.com/wp-content/uploads/video.ogv" type='video/ogg'></source> </video>
The media attribute lets you specify a CSS3 Media Query. The max-device-width of 480px = iPhone. So desktop browsers will use the video.mp4 while the iPhone uses the video.iphone.mp4. I’ve confirmed that this works properly with Chrome.
It’s interesting to see that browsers can do this reasonably well, even if you do have to make a few different versions of the video.
Shortcode Plugin
At the suggestion of ipstenu in the comments below, I made this into a shortcode plugin. You can download it here:
HTML5 Video Shortcode.
This plugin has the advantage of being ignored by TinyMCE. 🙂
Now that’s something I’d love to see shortcoded up…
[video ogg= mp4= iphone=]
Huh. That honestly never would have occurred to me. Dunno why, it’s obvious really.
Here you go. It wants full URLs for those three parameters. It also accepts width and height, optionally. Without them, it uses the the default embed sizes from WordPress or the theme (which actually works super well, BTW).
http://ottopress.com/files/2011/06/html5video.zip
Sometimes the obvious … Amusingly your code looks really close to what I fiddled with on Sunday 😉
The only ‘problem’ I have with HTML5 video is that too many of my site visitors are using IE 7 and 8, which don’t like HTML5 videos. I ended up tossing a wrapper around it ‘If less than IE 9, then show old ugly videos.’
No need for crazy useragent checking. The way the video tag works is that if the video format isn’t supported, the other content inside the tag is displayed instead. So just by adding the flash stuff (or whatever) after those three sources you can specify the HTML to be shown instead in IE8 and such (IE7 is insecure, I wouldn’t use it and I’d tell site visitors to upgrade).
To do it with the shortcode, just include the content inside the shortcode. [video ...](extra content)[/video] will work just fine.
Thank you very much for this post, BUT: full URLS are absolutely EVIL! Relocating a site with full URLs in post code is a real PITA, so please do not release this kind of timebomb into the public without warning people aboit what having full URLs in post content really means! Please always use relative URLs or use some defines from wp-config, but never, never, never ever use full URLS! THANKS!
Relative URLs are actually more evil, and you should always use absolute URLs. Two main reasons:
1. Absolute URLs are easier to change with a global search and replace. Relative URLs are difficult to alter later and make the regular expressions needed to do so much more difficult to create.
2. Your content is not only displayed on the website. It may also be displayed in feeds, or it may be aggregated. Absolute URLs will maintain the connections between the content and the things linked to from there. Relative URLs will not, since now they’re relative to… what, exactly? Relative URLs make an inherent assumption that they live in a specific place, but your content doesn’t need to live in only one place.
Use absolute URLs. Always.
[…] HTML5 Video Shortcode allows you to quickly and easily add HTML5 Video tags as a shortcode. […]
“Future versions of Firefox will support the WebM format instead (Chrome supports it now), so when Firefox 4 comes out, use that format.”
Is this an old post? Firefox 4 was released back in March and Firefox 5 was just released yesterday.
These browsers support WebM right now:
Firefox 4+
Chrome 6+
Opera 10.60+
IE 9 with the WebM for IE9 codec plugin installed
Safari 3.1+ for Mac with the Perian QuickTime Component v1.2.2+ installed
Of course, to ensure the video works in IE 9 and Safari 3.1+ on all platforms (Windows, Mac, iPhone), you should use H.264 (Baseline Profile) video with AAC (low-complexity) audio in an mp4 container (like you described in the article).
You can use Theora/Vorbis in an OGG (ogv) container to support older versions of Firefox (3.5+), Chrome (5+) and Opera (10.50+) if necessary.
However, WebM is arguably higher quality than OGG, so it’s probably best to stick with that.
Probably some parts of the post are old, yes. I tend to write ideas for posts down as drafts, then fill them out later when I have a reason to post them. So I have a fair amount of partially written posts lying around, and every once in a while I dust one off, fix it up, and post it.
I did try WebM when doing this, but noticed that the filesize was significantly bigger than the ogv was. Around double. Since the quality wasn’t any better, I stuck with the ogv instead..
Really? In my experience WebM is usually only slightly larger than Ogg at the same bitrate and noticeably sharper with less artifacting. I use FFmpeg (and also FFmpeg2Theora) to transcode videos. It looks like Miro uses the same thing, so I’m not sure why you’re getting different results. Maybe Miro is using older versions of FFmpeg and FFmpeg2Theora that are missing some enhancements to the encoders? Maybe it was just the quality of the source material?
In any case, I guess it doesn’t really matter since you’re getting the same (actually slightly better) browser support using Ogg instead of WebM.
This code can’t work in IE 8 & firefox.
Works fine in Firefox, because of the OGV support.
IE8 doesn’t do HTML 5 video. Upgrade to IE9.
Thanks for this OTTO! With regard to older browsers .. we’d just be placing in the full embed & object method within the opening and closing tags of the video shortcode correct?
I wouldn’t recommend only using H.264 Baseline across all deployments. H.264 Main profile should be targeted to tablets/desktops, and H.264 Baseline should be targeted to smartphones. The tag’s type attribute can use an extended value that includes the video codec used in the MP4 file, which is used by the playback device to determine its capabilities for rendering it.